home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / strlib.zip / STRREPL.C < prev    next >
Text File  |  1993-01-04  |  2KB  |  66 lines

  1.  
  2. /*  File   : strrepl.c
  3.     Author : Richard A. O'Keefe.
  4.     Updated: 23 April 1984
  5.     Defines: strrepl()
  6.  
  7.     strrepl(dst, src, pat, rep, times) copies src to dst, replacing  the
  8.     first "times" non-overlapping instances of pat by rep.  pat is not a
  9.     regex(3) pattern, it is a  literal  string  which  must  be  matched
  10.     exactly.   As  a  special hack, since strfind claims to find "" just
  11.     once at the end of the src string, strrepl does a strcat when pat is
  12.     an empty string "".  If times <= 0, it is just strmov.
  13.  
  14.     The result is a pointer to the NUL which now terminates dst.
  15.  
  16.     BEWARE: even when rep is shorter than pat it is NOT necessarily safe
  17.     for dst to be the same as src.  ALWAYS make sure dst and src do not/
  18.     will not overlap.  You have been warned.
  19.  
  20.     There really ought to be a strnrepl with a bound for the size of the
  21.     destination string, but there isn't.
  22. */
  23.  
  24. #include "strings.h"
  25. #include "_str2pat.h"
  26.  
  27. char *strrepl(dst, src, pat, rep, times)
  28.     char *dst, *src, *pat, *rep;
  29.     int times;
  30.     {
  31.         register char *s, *p;
  32.         register int c, lastch;
  33.  
  34.         pat = _str2pat(pat);
  35.         if (times <= 0) {
  36.             for (p = dst, s = src; *p++ = *s++; ) ;
  37.             return p-1;
  38.         }
  39.         if (_pat_lim < 0) {
  40.             for (p = dst, s = src; *p++ = *s++; ) ;
  41.             for (--p, s = rep; *p++ = *s++; ) ;
  42.             return p-1;
  43.         }
  44.         /*  The pattern is non-empty and times is positive  */
  45.         c = _pat_lim, lastch = pat[c];
  46.         for (;;) {
  47.             for (s = src, p = dst; --c >= 0; )
  48.                 if (!(*p++ = *s++)) return p-1;
  49.             c = *s, src = s, dst = p;
  50.             if (c == lastch) {
  51.                 for (s -= _pat_lim, p = pat; *p; )
  52.                     if (*s++ != *p++) goto not_yet;
  53.                 for (p = dst-_pat_lim, s = rep; *p++ = *s++; ) ;
  54.                 --p;
  55.                 if (--times == 0) {
  56.                     for (s = src; *p++ = *++s; ) ;
  57.                     return p-1;
  58.                 }
  59.                 dst = p, src++, c = _pat_lim;
  60.             } else {
  61. not_yet:        c = _pat_vec[c];
  62.             }
  63.         }
  64.     }
  65.  
  66.